<!DOCTYPE html>

<html>
<head>
  <title>#</title>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
  <link rel="stylesheet" media="all" href="docco.css" />
</head>
<body>
  <div id="container">
    <div id="background"></div>
    
      <ul id="jump_to">
        <li>
          <a class="large" href="javascript:void(0);">Jump To &hellip;</a>
          <a class="small" href="javascript:void(0);">+</a>
          <div id="jump_wrapper">
          <div id="jump_page">
            
              
              <a class="source" href="analyze.html">
                analyze.coffee
              </a>
            
              
              <a class="source" href="autoload.html">
                autoload.coffee
              </a>
            
              
              <a class="source" href="blender.html">
                blender.coffee
              </a>
            
              
              <a class="source" href="calculate.html">
                calculate.coffee
              </a>
            
              
              <a class="source" href="caman.html">
                caman.coffee
              </a>
            
              
              <a class="source" href="convert.html">
                convert.coffee
              </a>
            
              
              <a class="source" href="event.html">
                event.coffee
              </a>
            
              
              <a class="source" href="filter.html">
                filter.coffee
              </a>
            
              
              <a class="source" href="io.html">
                io.coffee
              </a>
            
              
              <a class="source" href="layer.html">
                layer.coffee
              </a>
            
              
              <a class="source" href="logger.html">
                logger.coffee
              </a>
            
              
              <a class="source" href="module.html">
                module.coffee
              </a>
            
              
              <a class="source" href="pixel.html">
                pixel.coffee
              </a>
            
              
              <a class="source" href="plugin.html">
                plugin.coffee
              </a>
            
              
              <a class="source" href="renderer.html">
                renderer.coffee
              </a>
            
              
              <a class="source" href="store.html">
                store.coffee
              </a>
            
              
              <a class="source" href="util.html">
                util.coffee
              </a>
            
              
              <a class="source" href="blenders.html">
                blenders.coffee
              </a>
            
              
              <a class="source" href="filters.html">
                filters.coffee
              </a>
            
              
              <a class="source" href="size.html">
                size.coffee
              </a>
            
              
              <a class="source" href="blur.html">
                blur.coffee
              </a>
            
              
              <a class="source" href="camera.html">
                camera.coffee
              </a>
            
              
              <a class="source" href="compoundBlur.html">
                compoundBlur.coffee
              </a>
            
              
              <a class="source" href="edges.html">
                edges.coffee
              </a>
            
              
              <a class="source" href="posterize.html">
                posterize.coffee
              </a>
            
              
              <a class="source" href="presets.html">
                presets.coffee
              </a>
            
              
              <a class="source" href="rotate.html">
                rotate.coffee
              </a>
            
              
              <a class="source" href="stackBlur.html">
                stackBlur.coffee
              </a>
            
              
              <a class="source" href="threshold.html">
                threshold.coffee
              </a>
            
          </div>
        </li>
      </ul>
    
    <ul class="sections">
        
        
        
        <li id="section-1">
            <div class="annotation">
              
              <div class="pilwrap for-h1">
                <a class="pilcrow" href="#section-1">&#182;</a>
              </div>
              <h1>#</h1>

            </div>
            
            <div class="content"><div class='highlight'><pre>CompoundBlur - Blurring <span class="reserved">with</span> varying radii <span class="keyword">for</span> Canvas

Version:   <span class="number">0.1</span>
Author:  Mario Klingemann
Contact:   mario<span class="property">@quasimondo</span>.com
Website:  http:<span class="regexp">//</span>www.quasimondo.com/StackBlurForCanvas
Twitter:  <span class="property">@quasimondo</span>
Modified By: Ryan LeFevre (<span class="property">@meltingice</span>)

In <span class="reserved">case</span> you find <span class="keyword">this</span> <span class="class"><span class="keyword">class</span> <span class="title">useful</span> - <span class="title">especially</span> <span class="title">in</span> <span class="title">commercial</span> <span class="title">projects</span> -</span>
I am <span class="keyword">not</span> totally unhappy <span class="keyword">for</span> a small donation to my PayPal account
mario<span class="property">@quasimondo</span>.de

Copyright (c) <span class="number">2011</span> Mario Klingemann

Permission <span class="keyword">is</span> hereby granted, free <span class="keyword">of</span> charge, to any person
obtaining a copy <span class="keyword">of</span> <span class="keyword">this</span> software <span class="keyword">and</span> associated documentation
files (the <span class="string">"Software"</span>), to deal <span class="keyword">in</span> the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, <span class="keyword">and</span>/<span class="keyword">or</span> sell
copies <span class="keyword">of</span> the Software, <span class="keyword">and</span> to permit persons to whom the
Software <span class="keyword">is</span> furnished to <span class="keyword">do</span> so, subject to the following
conditions:

The above copyright notice <span class="keyword">and</span> <span class="keyword">this</span> permission notice shall be
included <span class="keyword">in</span> all copies <span class="keyword">or</span> substantial portions <span class="keyword">of</span> the Software.

THE SOFTWARE IS PROVIDED <span class="string">"AS IS"</span>, WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.</pre></div></div>
            
        </li>
        
        
        <li id="section-2">
            <div class="annotation">
              
              <div class="pilwrap for-h1">
                <a class="pilcrow" href="#section-2">&#182;</a>
              </div>
              <h1>#</h1>
<p>Wrapping this in a closure since there&#39;s a bunch of extra functions this plugin requires
and we don&#39;t want them clogging up the global scope.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="keyword">do</span> -&gt;
  mul_table = [
    <span class="number">512</span>, <span class="number">512</span>, <span class="number">456</span>, <span class="number">512</span>, <span class="number">328</span>, <span class="number">456</span>, <span class="number">335</span>, <span class="number">512</span>, <span class="number">405</span>, <span class="number">328</span>, <span class="number">271</span>, <span class="number">456</span>, <span class="number">388</span>, <span class="number">335</span>, <span class="number">292</span>, <span class="number">512</span>, <span class="number">454</span>, <span class="number">405</span>, <span class="number">364</span>, <span class="number">328</span>, <span class="number">298</span>, <span class="number">271</span>, <span class="number">496</span>, <span class="number">456</span>, <span class="number">420</span>, <span class="number">388</span>, <span class="number">360</span>, <span class="number">335</span>, <span class="number">312</span>, <span class="number">292</span>, <span class="number">273</span>, <span class="number">512</span>, <span class="number">482</span>, <span class="number">454</span>, <span class="number">428</span>, <span class="number">405</span>, <span class="number">383</span>, <span class="number">364</span>, <span class="number">345</span>, <span class="number">328</span>, <span class="number">312</span>, <span class="number">298</span>, <span class="number">284</span>, <span class="number">271</span>, <span class="number">259</span>, <span class="number">496</span>, <span class="number">475</span>, <span class="number">456</span>, <span class="number">437</span>, <span class="number">420</span>, <span class="number">404</span>, <span class="number">388</span>, <span class="number">374</span>, <span class="number">360</span>, <span class="number">347</span>, <span class="number">335</span>, <span class="number">323</span>, <span class="number">312</span>, <span class="number">302</span>, <span class="number">292</span>, <span class="number">282</span>, <span class="number">273</span>, <span class="number">265</span>, <span class="number">512</span>, <span class="number">497</span>, <span class="number">482</span>, <span class="number">468</span>, <span class="number">454</span>, <span class="number">441</span>, <span class="number">428</span>, <span class="number">417</span>, <span class="number">405</span>, <span class="number">394</span>, <span class="number">383</span>, <span class="number">373</span>, <span class="number">364</span>, <span class="number">354</span>, <span class="number">345</span>, <span class="number">337</span>, <span class="number">328</span>, <span class="number">320</span>, <span class="number">312</span>, <span class="number">305</span>, <span class="number">298</span>, <span class="number">291</span>, <span class="number">284</span>, <span class="number">278</span>, <span class="number">271</span>, <span class="number">265</span>, <span class="number">259</span>, <span class="number">507</span>, <span class="number">496</span>, <span class="number">485</span>, <span class="number">475</span>, <span class="number">465</span>, <span class="number">456</span>, <span class="number">446</span>, <span class="number">437</span>, <span class="number">428</span>, <span class="number">420</span>, <span class="number">412</span>, <span class="number">404</span>, <span class="number">396</span>, <span class="number">388</span>, <span class="number">381</span>, <span class="number">374</span>, <span class="number">367</span>, <span class="number">360</span>, <span class="number">354</span>, <span class="number">347</span>, <span class="number">341</span>, <span class="number">335</span>, <span class="number">329</span>, <span class="number">323</span>, <span class="number">318</span>, <span class="number">312</span>, <span class="number">307</span>, <span class="number">302</span>, <span class="number">297</span>, <span class="number">292</span>, <span class="number">287</span>, <span class="number">282</span>, <span class="number">278</span>, <span class="number">273</span>, <span class="number">269</span>, <span class="number">265</span>, <span class="number">261</span>, <span class="number">512</span>, <span class="number">505</span>, <span class="number">497</span>, <span class="number">489</span>, <span class="number">482</span>, <span class="number">475</span>, <span class="number">468</span>, <span class="number">461</span>, <span class="number">454</span>, <span class="number">447</span>, <span class="number">441</span>, <span class="number">435</span>, <span class="number">428</span>, <span class="number">422</span>, <span class="number">417</span>, <span class="number">411</span>, <span class="number">405</span>, <span class="number">399</span>, <span class="number">394</span>, <span class="number">389</span>, <span class="number">383</span>, <span class="number">378</span>, <span class="number">373</span>, <span class="number">368</span>, <span class="number">364</span>, <span class="number">359</span>, <span class="number">354</span>, <span class="number">350</span>, <span class="number">345</span>, <span class="number">341</span>, <span class="number">337</span>, <span class="number">332</span>, <span class="number">328</span>, <span class="number">324</span>, <span class="number">320</span>, <span class="number">316</span>, <span class="number">312</span>, <span class="number">309</span>, <span class="number">305</span>, <span class="number">301</span>, <span class="number">298</span>, <span class="number">294</span>, <span class="number">291</span>, <span class="number">287</span>, <span class="number">284</span>, <span class="number">281</span>, <span class="number">278</span>, <span class="number">274</span>, <span class="number">271</span>, <span class="number">268</span>, <span class="number">265</span>, <span class="number">262</span>, <span class="number">259</span>, <span class="number">257</span>, <span class="number">507</span>, <span class="number">501</span>, <span class="number">496</span>, <span class="number">491</span>, <span class="number">485</span>, <span class="number">480</span>, <span class="number">475</span>, <span class="number">470</span>, <span class="number">465</span>, <span class="number">460</span>, <span class="number">456</span>, <span class="number">451</span>, <span class="number">446</span>, <span class="number">442</span>, <span class="number">437</span>, <span class="number">433</span>, <span class="number">428</span>, <span class="number">424</span>, <span class="number">420</span>, <span class="number">416</span>, <span class="number">412</span>, <span class="number">408</span>, <span class="number">404</span>, <span class="number">400</span>, <span class="number">396</span>, <span class="number">392</span>, <span class="number">388</span>, <span class="number">385</span>, <span class="number">381</span>, <span class="number">377</span>, <span class="number">374</span>, <span class="number">370</span>, <span class="number">367</span>, <span class="number">363</span>, <span class="number">360</span>, <span class="number">357</span>, <span class="number">354</span>, <span class="number">350</span>, <span class="number">347</span>, <span class="number">344</span>, <span class="number">341</span>, <span class="number">338</span>, <span class="number">335</span>, <span class="number">332</span>, <span class="number">329</span>, <span class="number">326</span>, <span class="number">323</span>, <span class="number">320</span>, <span class="number">318</span>, <span class="number">315</span>, <span class="number">312</span>, <span class="number">310</span>, <span class="number">307</span>, <span class="number">304</span>, <span class="number">302</span>, <span class="number">299</span>, <span class="number">297</span>, <span class="number">294</span>, <span class="number">292</span>, <span class="number">289</span>, <span class="number">287</span>, <span class="number">285</span>, <span class="number">282</span>, <span class="number">280</span>, <span class="number">278</span>, <span class="number">275</span>, <span class="number">273</span>, <span class="number">271</span>, <span class="number">269</span>, <span class="number">267</span>, <span class="number">265</span>, <span class="number">263</span>, <span class="number">261</span>, <span class="number">259</span>]


  shg_table = [
    <span class="number">9</span>, <span class="number">11</span>, <span class="number">12</span>, <span class="number">13</span>, <span class="number">13</span>, <span class="number">14</span>, <span class="number">14</span>, <span class="number">15</span>, <span class="number">15</span>, <span class="number">15</span>, <span class="number">15</span>, <span class="number">16</span>, <span class="number">16</span>, <span class="number">16</span>, <span class="number">16</span>, <span class="number">17</span>, <span class="number">17</span>, <span class="number">17</span>, <span class="number">17</span>, <span class="number">17</span>, <span class="number">17</span>, <span class="number">17</span>, <span class="number">18</span>, <span class="number">18</span>, <span class="number">18</span>, <span class="number">18</span>, <span class="number">18</span>, <span class="number">18</span>, <span class="number">18</span>, <span class="number">18</span>, <span class="number">18</span>, <span class="number">19</span>, <span class="number">19</span>, <span class="number">19</span>, <span class="number">19</span>, <span class="number">19</span>, <span class="number">19</span>, <span class="number">19</span>, <span class="number">19</span>, <span class="number">19</span>, <span class="number">19</span>, <span class="number">19</span>, <span class="number">19</span>, <span class="number">19</span>, <span class="number">19</span>, <span class="number">20</span>, <span class="number">20</span>, <span class="number">20</span>, <span class="number">20</span>, <span class="number">20</span>, <span class="number">20</span>, <span class="number">20</span>, <span class="number">20</span>, <span class="number">20</span>, <span class="number">20</span>, <span class="number">20</span>, <span class="number">20</span>, <span class="number">20</span>, <span class="number">20</span>, <span class="number">20</span>, <span class="number">20</span>, <span class="number">20</span>, <span class="number">20</span>, <span class="number">21</span>, <span class="number">21</span>, <span class="number">21</span>, <span class="number">21</span>, <span class="number">21</span>, <span class="number">21</span>, <span class="number">21</span>, <span class="number">21</span>, <span class="number">21</span>, <span class="number">21</span>, <span class="number">21</span>, <span class="number">21</span>, <span class="number">21</span>, <span class="number">21</span>, <span class="number">21</span>, <span class="number">21</span>, <span class="number">21</span>, <span class="number">21</span>, <span class="number">21</span>, <span class="number">21</span>, <span class="number">21</span>, <span class="number">21</span>, <span class="number">21</span>, <span class="number">21</span>, <span class="number">21</span>, <span class="number">21</span>, <span class="number">21</span>, <span class="number">22</span>, <span class="number">22</span>, <span class="number">22</span>, <span class="number">22</span>, <span class="number">22</span>, <span class="number">22</span>, <span class="number">22</span>, <span class="number">22</span>, <span class="number">22</span>, <span class="number">22</span>, <span class="number">22</span>, <span class="number">22</span>, <span class="number">22</span>, <span class="number">22</span>, <span class="number">22</span>, <span class="number">22</span>, <span class="number">22</span>, <span class="number">22</span>, <span class="number">22</span>, <span class="number">22</span>, <span class="number">22</span>, <span class="number">22</span>, <span class="number">22</span>, <span class="number">22</span>, <span class="number">22</span>, <span class="number">22</span>, <span class="number">22</span>, <span class="number">22</span>, <span class="number">22</span>, <span class="number">22</span>, <span class="number">22</span>, <span class="number">22</span>, <span class="number">22</span>, <span class="number">22</span>, <span class="number">22</span>, <span class="number">22</span>, <span class="number">22</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">23</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>, <span class="number">24</span>]

  <span class="function"><span class="title">getLinearGradientMap</span></span> = (width, height, centerX, centerY, angle, length, mirrored) -&gt;
    cnv = <span class="keyword">if</span> exports? <span class="keyword">then</span> <span class="keyword">new</span> Canvas() <span class="keyword">else</span> document.createElement(<span class="string">'canvas'</span>)
    cnv.width = width
    cnv.height = height

    x1 = centerX + Math.cos(angle) * length * <span class="number">0.5</span>
    y1 = centerY + Math.sin(angle) * length * <span class="number">0.5</span>

    x2 = centerX - Math.cos(angle) * length * <span class="number">0.5</span>
    y2 = centerY - Math.sin(angle) * length * <span class="number">0.5</span>

    context = cnv.getContext(<span class="string">"2d"</span>)
    gradient = context.createLinearGradient(x1, y1, x2, y2)
    <span class="keyword">if</span> <span class="keyword">not</span> mirrored
      gradient.addColorStop(<span class="number">0</span>, <span class="string">"white"</span>)
      gradient.addColorStop(<span class="number">1</span>, <span class="string">"black"</span>)
    <span class="keyword">else</span>
      gradient.addColorStop(<span class="number">0</span>, <span class="string">"white"</span>)
      gradient.addColorStop(<span class="number">0.5</span>, <span class="string">"black"</span>)
      gradient.addColorStop(<span class="number">1</span>, <span class="string">"white"</span>)
    
    context.fillStyle = gradient
    context.fillRect(<span class="number">0</span>, <span class="number">0</span>, width, height)
    <span class="keyword">return</span> context.getImageData(<span class="number">0</span>, <span class="number">0</span>, width, height)

  <span class="function"><span class="title">getRadialGradientMap</span></span> = (width, height, centerX, centerY, radius1, radius2) -&gt;
    cnv = <span class="keyword">if</span> exports? <span class="keyword">then</span> <span class="keyword">new</span> Canvas() <span class="keyword">else</span> document.createElement(<span class="string">'canvas'</span>)
    cnv.width = width
    cnv.height = height

    context = cnv.getContext(<span class="string">"2d"</span>)
    gradient = context.createRadialGradient(centerX, centerY, radius1, centerX, centerY, radius2)

    gradient.addColorStop(<span class="number">1</span>, <span class="string">"white"</span>)
    gradient.addColorStop(<span class="number">0</span>, <span class="string">"black"</span>)

    context.fillStyle = gradient
    context.fillRect(<span class="number">0</span>, <span class="number">0</span>, width, height)
    <span class="keyword">return</span> context.getImageData(<span class="number">0</span>, <span class="number">0</span>, width, height)

  <span class="function"><span class="title">BlurStack</span></span> = -&gt;
    <span class="property">@r</span> = <span class="number">0</span>
    <span class="property">@g</span> = <span class="number">0</span>
    <span class="property">@b</span> = <span class="number">0</span>
    <span class="property">@a</span> = <span class="number">0</span>
    <span class="property">@next</span> = <span class="literal">null</span>

  Caman.Plugin.register <span class="string">"compoundBlur"</span>, (radiusData, radius, increaseFactor, blurLevels) -&gt;
    width = <span class="property">@dimensions</span>.width
    height = <span class="property">@dimensions</span>.height

    imagePixels = <span class="property">@pixelData</span>
    radiusPixels = radiusData.data

    wh = width * height
    wh4 = wh &lt;&lt; <span class="number">2</span>
    pixels = []

    pixels[i] = imagePixels[i] <span class="keyword">for</span> i <span class="keyword">in</span> [<span class="number">0.</span>..wh4]
      
    currentIndex = <span class="number">0</span>
    steps = blurLevels
    blurLevels -= <span class="number">1</span>

    <span class="keyword">while</span> steps-- &gt;= <span class="number">0</span>
      iradius = (radius + <span class="number">0.5</span>) | <span class="number">0</span>
      <span class="keyword">continue</span> <span class="keyword">if</span> iradius <span class="keyword">is</span> <span class="number">0</span>
      iradius = <span class="number">256</span> <span class="keyword">if</span> iradius &gt; <span class="number">256</span>

      div = iradius + iradius + <span class="number">1</span>
      w4 = width &lt;&lt; <span class="number">2</span>
      widthMinus1 = width - <span class="number">1</span>
      heightMinus1 = height - <span class="number">1</span>
      radiusPlus1 = iradius + <span class="number">1</span>
      sumFactor = radiusPlus1 * (radiusPlus1 + <span class="number">1</span>) / <span class="number">2</span>

      stackStart = <span class="keyword">new</span> BlurStack()
      stackEnd = <span class="literal">undefined</span>
      stack = stackStart
      
      <span class="keyword">for</span> i <span class="keyword">in</span> [<span class="number">1.</span>..div]
        stack = stack.next = <span class="keyword">new</span> BlurStack()
        stackEnd = stack <span class="keyword">if</span> i <span class="keyword">is</span> radiusPlus1
      
      stack.next = stackStart
      stackIn = <span class="literal">null</span>
      stackOut = <span class="literal">null</span>

      yw = yi = <span class="number">0</span>

      mul_sum = mul_table[iradius]
      shg_sum = shg_table[iradius]

      <span class="keyword">for</span> y <span class="keyword">in</span> [<span class="number">0.</span>..height]
        r_in_sum = g_in_sum = b_in_sum = r_sum = g_sum = b_sum = <span class="number">0</span>

        r_out_sum = radiusPlus1 * (pr = pixels[yi])
        g_out_sum = radiusPlus1 * (pg = pixels[yi + <span class="number">1</span>])
        b_out_sum = radiusPlus1 * (pb = pixels[yi + <span class="number">2</span>])

        r_sum += sumFactor * pr
        g_sum += sumFactor * pg
        b_sum += sumFactor * pb

        stack = stackStart
        
        <span class="keyword">for</span> i <span class="keyword">in</span> [<span class="number">0.</span>..radiusPlus1]
          stack.r = pr
          stack.g = pg
          stack.b = pb
          stack = stack.next
          
        <span class="keyword">for</span> i <span class="keyword">in</span> [<span class="number">1.</span>..radiusPlus1]
          p = yi + ((<span class="keyword">if</span> widthMinus1 &lt; i <span class="keyword">then</span> widthMinus1 <span class="keyword">else</span> i) &lt;&lt; <span class="number">2</span>)
          r_sum += (stack.r = (pr = pixels[p])) * (rbs = radiusPlus1 - i)
          g_sum += (stack.g = (pg = pixels[p + <span class="number">1</span>])) * rbs
          b_sum += (stack.b = (pb = pixels[p + <span class="number">2</span>])) * rbs

          r_in_sum += pr
          g_in_sum += pg
          b_in_sum += pb
          
          stack = stack.next
          
        stackIn = stackStart
        stackOut = stackEnd

        <span class="keyword">for</span> x <span class="keyword">in</span> [<span class="number">0.</span>..width]
          pixels[yi] = (r_sum * mul_sum) &gt;&gt; shg_sum
          pixels[yi + <span class="number">1</span>] = (g_sum * mul_sum) &gt;&gt; shg_sum
          pixels[yi + <span class="number">2</span>] = (b_sum * mul_sum) &gt;&gt; shg_sum

          r_sum -= r_out_sum
          g_sum -= g_out_sum
          b_sum -= b_out_sum

          r_out_sum -= stackIn.r
          g_out_sum -= stackIn.g
          b_out_sum -= stackIn.b

          p = (yw + (<span class="keyword">if</span> (p = x + radiusPlus1) &lt; widthMinus1 <span class="keyword">then</span> p <span class="keyword">else</span> widthMinus1)) &lt;&lt; <span class="number">2</span>

          r_in_sum += (stackIn.r = pixels[p])
          g_in_sum += (stackIn.g = pixels[p + <span class="number">1</span>])
          b_in_sum += (stackIn.b = pixels[p + <span class="number">2</span>])

          r_sum += r_in_sum
          g_sum += g_in_sum
          b_sum += b_in_sum

          stackIn = stackIn.next

          r_out_sum += (pr = stackOut.r)
          g_out_sum += (pg = stackOut.g)
          b_out_sum += (pb = stackOut.b)

          r_in_sum -= pr
          g_in_sum -= pg
          b_in_sum -= pb

          stackOut = stackOut.next

          yi += <span class="number">4</span>
          
        yw += width
        
      <span class="keyword">for</span> x <span class="keyword">in</span> [<span class="number">0.</span>..width]
        g_in_sum = b_in_sum = r_in_sum = g_sum = b_sum = r_sum = <span class="number">0</span>

        yi = x &lt;&lt; <span class="number">2</span>
        r_out_sum = radiusPlus1 * (pr = pixels[yi])
        g_out_sum = radiusPlus1 * (pg = pixels[yi + <span class="number">1</span>])
        b_out_sum = radiusPlus1 * (pb = pixels[yi + <span class="number">2</span>])
        
        r_sum += sumFactor * pr
        g_sum += sumFactor * pg
        b_sum += sumFactor * pb
        
        stack = stackStart
        
        <span class="keyword">for</span> i <span class="keyword">in</span> [<span class="number">0.</span>..radiusPlus1]
          stack.r = pr
          stack.g = pg
          stack.b = pb
          stack = stack.next
          
        yp = width

        <span class="keyword">for</span> i <span class="keyword">in</span> [<span class="number">1.</span>..radiusPlus1]
          yi = (yp + x) &lt;&lt; <span class="number">2</span>
          r_sum += (stack.r = (pr = pixels[yi])) * (rbs = radiusPlus1 - i)
          g_sum += (stack.g = (pg = pixels[yi + <span class="number">1</span>])) * rbs
          b_sum += (stack.b = (pb = pixels[yi + <span class="number">2</span>])) * rbs
          r_in_sum += pr
          g_in_sum += pg
          b_in_sum += pb
          stack = stack.next
          yp += width  <span class="keyword">if</span> i &lt; heightMinus1
          
        yi = x
        stackIn = stackStart
        stackOut = stackEnd
        
        <span class="keyword">for</span> y <span class="keyword">in</span> [<span class="number">0.</span>..height]
          p = yi &lt;&lt; <span class="number">2</span>
          pixels[p] = (r_sum * mul_sum) &gt;&gt; shg_sum
          pixels[p + <span class="number">1</span>] = (g_sum * mul_sum) &gt;&gt; shg_sum
          pixels[p + <span class="number">2</span>] = (b_sum * mul_sum) &gt;&gt; shg_sum

          r_sum -= r_out_sum
          g_sum -= g_out_sum
          b_sum -= b_out_sum

          r_out_sum -= stackIn.r
          g_out_sum -= stackIn.g
          b_out_sum -= stackIn.b

          p = (x + ((<span class="keyword">if</span> (p = y + radiusPlus1) &lt; heightMinus1 <span class="keyword">then</span> p <span class="keyword">else</span> heightMinus1) * width)) &lt;&lt; <span class="number">2</span>
          
          r_sum += (r_in_sum += (stackIn.r = pixels[p]))
          g_sum += (g_in_sum += (stackIn.g = pixels[p + <span class="number">1</span>]))
          b_sum += (b_in_sum += (stackIn.b = pixels[p + <span class="number">2</span>]))
          
          stackIn = stackIn.next
          
          r_out_sum += (pr = stackOut.r)
          g_out_sum += (pg = stackOut.g)
          b_out_sum += (pb = stackOut.b)
          
          r_in_sum -= pr
          g_in_sum -= pg
          b_in_sum -= pb
          
          stackOut = stackOut.next
          
          yi += width
          
      radius *= increaseFactor

      i = wh
      <span class="keyword">while</span> --i &gt; -<span class="number">1</span>
        idx = i &lt;&lt; <span class="number">2</span>
        lookupValue = (radiusPixels[idx + <span class="number">2</span>] &amp; <span class="number">0xff</span>) / <span class="number">255.0</span> * blurLevels
        index = lookupValue | <span class="number">0</span>

        <span class="keyword">if</span> index <span class="keyword">is</span> currentIndex
          blend = <span class="number">256.0</span> * (lookupValue - (lookupValue | <span class="number">0</span>))
          iblend = <span class="number">256</span> - blend
        
          imagePixels[idx] = (imagePixels[idx] * iblend + pixels[idx] * blend) &gt;&gt; <span class="number">8</span>
          imagePixels[idx + <span class="number">1</span>] = (imagePixels[idx + <span class="number">1</span>] * iblend + pixels[idx + <span class="number">1</span>] * blend) &gt;&gt; <span class="number">8</span>
          imagePixels[idx + <span class="number">2</span>] = (imagePixels[idx + <span class="number">2</span>] * iblend + pixels[idx + <span class="number">2</span>] * blend) &gt;&gt; <span class="number">8</span>
        <span class="keyword">else</span> <span class="keyword">if</span> index <span class="keyword">is</span> currentIndex + <span class="number">1</span>
          imagePixels[idx] = pixels[idx]
          imagePixels[idx + <span class="number">1</span>] = pixels[idx + <span class="number">1</span>]
          imagePixels[idx + <span class="number">2</span>] = pixels[idx + <span class="number">2</span>]
      currentIndex++

    <span class="keyword">return</span> @

  Caman.Filter.register <span class="string">"tiltShift"</span>, (opts) -&gt;
    defaults =
      center:
        x: <span class="property">@dimensions</span>.width / <span class="number">2</span>
        y: <span class="property">@dimensions</span>.height / <span class="number">2</span>
      angle: <span class="number">45</span>
      focusWidth: <span class="number">200</span>
      startRadius: <span class="number">3</span>
      radiusFactor: <span class="number">1.5</span>
      steps: <span class="number">3</span>

    opts = Util.extend defaults, opts
    opts.angle *= Math.PI / <span class="number">180</span>
    gradient = getLinearGradientMap(<span class="property">@dimensions</span>.width, <span class="property">@dimensions</span>.height, opts.center.x, opts.center.y, opts.angle, opts.focusWidth, <span class="literal">true</span>)

    <span class="property">@processPlugin</span> <span class="string">"compoundBlur"</span>, [gradient, opts.startRadius, opts.radiusFactor, opts.steps]

  Caman.Filter.register <span class="string">"radialBlur"</span>, (opts) -&gt;
    defaults =
      size: <span class="number">50</span>
      center:
        x: <span class="property">@dimensions</span>.width / <span class="number">2</span>
        y: <span class="property">@dimensions</span>.height / <span class="number">2</span>
      startRadius: <span class="number">3</span>
      radiusFactor: <span class="number">1.5</span>
      steps: <span class="number">3</span>
      radius: <span class="literal">null</span>

    opts = Util.extend defaults, opts

    <span class="keyword">if</span> <span class="keyword">not</span> opts.radius
      opts.radius = <span class="keyword">if</span> <span class="property">@dimensions</span>.width &lt; <span class="property">@dimensions</span>.height <span class="keyword">then</span> <span class="property">@dimensions</span>.height <span class="keyword">else</span> <span class="property">@dimensions</span>.width

    radius1 = (opts.radius / <span class="number">2</span>) - opts.size
    radius2 = (opts.radius / <span class="number">2</span>)

    gradient = getRadialGradientMap(<span class="property">@dimensions</span>.width, <span class="property">@dimensions</span>.height, opts.center.x, opts.center.y, radius1, radius2)

    <span class="property">@processPlugin</span> <span class="string">"compoundBlur"</span>, [gradient, opts.startRadius, opts.radiusFactor, opts.steps]</pre></div></div>
            
        </li>
        
    </ul>
  </div>
</body>
</html>
